package zhh.tangbao.wechat.api.factory;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import zhh.tangbao.system.utils.ZhhStringUtil;

import java.nio.charset.StandardCharsets;

/**
 * <p>
 *     描述
 * </p>
 * @author 粥灰灰
 * <p>2023/3/14</p>
 */

@Slf4j
@Component
public class WeChatPayRequestBodyFactory {

    @Value("${wx.appId}")
    private String appId;

    @Value("${wx.mchId}")
    private String mchId;

    @Value("${wx.mchKey}")
    private String mchKey;

    @Value("${wx.tradeType}")
    private String tradeType;

    /** 支付结果回调地址 */
    @Value("${wx.notifyUrl}")
    private String notifyUrl;

    @Value("${wx.spbillCreateIp}")
    private String spbillCreateIp;

    /*
    参数顺序[
    appid, body, mch_id, nonce_str, notify_url, openid, out_trade_no,
    spbill_create_ip, total_fee, trade_type
     ]
     */

    /**
     * 生成统一下单接口需要的xml格式的请求体
     * @param openId 用户openid
     * @param commodityName 商品名称
     * @param orderId 订单编号
     */
    public String createRequestContent(String openId, String commodityName, String orderId, double price) {
        return createRequestContent(openId, commodityName, orderId, price, null);
    }

    /**
     * 生成统一下单接口需要的xml格式的请求体
     */
    public String createRequestContent(String openId, String commodityName, String orderId, double price, String nonceStr) {
        if (StrUtil.isEmpty(nonceStr)) {
            nonceStr = ZhhStringUtil.randomString32();
        }
        // 微信支付的单位是分，所以不需要浮点数记录，因为最低价格大于等于1分钱
        int p = (int) (price * 100);
        String originalSign = new StringBuilder()
                .append("appid=").append(appId)
                .append("&body=").append(commodityName)
                .append("&mch_id=").append(mchId)
                .append("&nonce_str=").append(nonceStr)
                .append("&notify_url=").append(notifyUrl)
                .append("&openid=").append(openId)
                .append("&out_trade_no=").append(orderId)
                .append("&spbill_create_ip=").append(spbillCreateIp)
                .append("&total_fee=").append(p)
                .append("&trade_type=").append(tradeType)
                .append("&key=").append(mchKey)
                .toString();

        String sign = DigestUtils.md5Hex(originalSign.getBytes(StandardCharsets.UTF_8));

        String xmlSign = new StringBuilder()
                .append("<xml><appid>").append(appId).append("</appid>")
                .append("<body>").append(commodityName).append("</body>")
                .append("<mch_id>").append(mchId).append("</mch_id>")
                .append("<nonce_str>").append(nonceStr).append("</nonce_str>")
                .append("<notify_url>").append(notifyUrl).append("</notify_url>")
                .append("<openid>").append(openId).append("</openid>")
                .append("<out_trade_no>").append(orderId).append("</out_trade_no>")
                .append("<spbill_create_ip>").append(spbillCreateIp).append("</spbill_create_ip>")
                .append("<total_fee>").append(p).append("</total_fee>")
                .append("<trade_type>").append(tradeType).append("</trade_type>")
                .append("<sign>").append(sign).append("</sign></xml>").toString();
        return xmlSign;
    }
}
